<template>
    <div class="scanner">
        <!-- <h2>Vue2 二维码 / 条形码 扫描</h2> -->

        <!-- 摄像头实时扫描 -->
        <video ref="video" autoplay muted playsinline class="video"></video>
        <div class="result">{{ result }}</div>

        <!-- 上传图片识别 -->
        <div class="upload">
            <input type="file" accept="image/*" @change="onFileChange" />
        </div>
    </div>
</template>

<script>
import {
    BrowserMultiFormatReader,
    NotFoundException,
    BarcodeFormat,
    DecodeHintType
} from "@zxing/library";

export default {
    name: "BarcodeScanner",
    data() {
        return {
            codeReader: null,
            result: "等待扫描结果...",
        };
    },
    mounted() {
        this.checkCamera().then(ok => {
            if (ok) {
                this.initScanner(); // 正常摄像头扫码
            } else {
                this.result = "摄像头不可用，请上传图片识别";
            }
        });
    },
    beforeDestroy() {
        if (this.codeReader) {
            this.codeReader.reset();
        }
    },
    methods: {
        stop() {
            if (this.codeReader) {
                this.codeReader.reset();
            }
        },
        async checkCamera() {
            try {
                const stream = await navigator.mediaDevices.getUserMedia({ video: true });
                stream.getTracks().forEach(track => track.stop()); // 先停掉
                return true;
            } catch (err) {
                console.warn("摄像头不可用:", err);
                return false;
            }
        },
        initScanner() {
            // 定义 hints，支持二维码 + 常见条码
            const hints = new Map();
            hints.set(DecodeHintType.POSSIBLE_FORMATS, [
                BarcodeFormat.QR_CODE,
                BarcodeFormat.CODE_128,
                BarcodeFormat.CODE_39,
                BarcodeFormat.EAN_13,
                BarcodeFormat.EAN_8,
                BarcodeFormat.UPC_A,
                BarcodeFormat.UPC_E,
            ]);

            this.codeReader = new BrowserMultiFormatReader(hints);

            this.codeReader
                .listVideoInputDevices()
                .then(videoInputDevices => {
                    if (videoInputDevices.length > 0) {
                        // 优先后置摄像头
                        let selectedDeviceId = videoInputDevices[0].deviceId;
                        const backCamera = videoInputDevices.find(device =>
                            device.label.toLowerCase().includes("back") ||
                            device.label.toLowerCase().includes("rear") ||
                            device.label.toLowerCase().includes("environment")
                        );
                        if (backCamera) {
                            selectedDeviceId = backCamera.deviceId;
                        }

                        // 开始摄像头扫码
                        this.codeReader.decodeFromVideoDevice(
                            selectedDeviceId,
                            this.$refs.video,
                            (result, err) => {
                                if (result) {
                                    this.result = "识别结果: " + result.getText();
                                    console.log("识别成功:", result);
                                    // 触发事件，将扫码结果传递给父组件
                                    this.$emit('scan-result', result.getText());
                                }
                                if (err && !(err instanceof NotFoundException)) {
                                    console.error("扫码出错:", err);
                                }
                            }
                        );
                    } else {
                        this.result = "没有检测到摄像头设备";
                    }
                })
                .catch(err => {
                    console.error(err);
                    this.result = "无法访问摄像头，请检查权限或使用 HTTPS 打开页面";
                });
        },

        // 处理图片上传
        onFileChange(event) {
            const file = event.target.files[0];
            if (!file) return;

            const reader = new FileReader();
            reader.onload = e => {
                const img = new Image();
                img.src = e.target.result;
                img.onload = () => {
                    this.codeReader
                        .decodeFromImage(img)
                        .then(result => {
                            this.result = "图片识别结果: " + result.getText();
                            console.log("图片识别成功:", result);
                            // 触发事件，将图片识别结果传递给父组件
                            this.$emit('scan-result', result.getText());
                        })
                        .catch(err => {
                            console.error("图片识别失败:", err);
                            this.result = "未识别到有效的二维码/条形码";
                        });
                };
            };
            reader.readAsDataURL(file);
        },
    },
};
</script>

<style scoped>
.scanner {
    text-align: center;
    padding: 20px;
}

.video {
    width: 100%;
    max-width: 400px;
    border: 2px solid #333;
    border-radius: 8px;
}

.result {
    margin-top: 20px;
    font-size: 18px;
    font-weight: bold;
    color: green;
}

.upload {
    margin-top: 20px;
}
</style>
